{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "32a780c1",
   "metadata": {},
   "source": [
    "# FlashRank reranker\n",
    "\n",
    ">[FlashRank](https://github.com/PrithivirajDamodaran/FlashRank)는 기존 검색 및 `retrieval` 파이프라인에 재순위를 추가하기 위한 초경량 및 초고속 Python 라이브러리입니다. 이는 SoTA `cross-encoders`를 기반으로 합니다.\n",
    "\n",
    "이 노트북은 문서 압축 및 `retrieval`을 위해 [flashrank](https://github.com/PrithivirajDamodaran/FlashRank)를 사용하는 방법을 보여줍니다.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d8a0f0d",
   "metadata": {},
   "source": [
    "## 환경설정"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c27423f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 설치\n",
    "# !pip install -qU flashrank"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2f7c15f1",
   "metadata": {},
   "outputs": [],
   "source": [
    "def pretty_print_docs(docs):\n",
    "    print(\n",
    "        f\"\\n{'-' * 100}\\n\".join(\n",
    "            [\n",
    "                f\"Document {i+1}:\\n\\n{d.page_content}\\nMetadata: {d.metadata}\"\n",
    "                for i, d in enumerate(docs)\n",
    "            ]\n",
    "        )\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f855d244",
   "metadata": {},
   "source": [
    "## FlashrankRerank"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aab8fde6",
   "metadata": {},
   "source": [
    "간단한 예시를 위한 데이터를 로드하고 retriever 를 생성합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "7caea834",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Document 1:\n",
      "\n",
      "Crawling\n",
      "\n",
      "정의: 크롤링은 자동화된 방식으로 웹 페이지를 방문하여 데이터를 수집하는 과정입니다. 이는 검색 엔진 최적화나 데이터 분석에 자주 사용됩니다.\n",
      "예시: 구글 검색 엔진이 인터넷 상의 웹사이트를 방문하여 콘텐츠를 수집하고 인덱싱하는 것이 크롤링입니다.\n",
      "연관키워드: 데이터 수집, 웹 스크래핑, 검색 엔진\n",
      "\n",
      "Word2Vec\n",
      "\n",
      "정의: Word2Vec은 단어를 벡터 공간에 매핑하여 단어 간의 의미적 관계를 나타내는 자연어 처리 기술입니다. 이는 단어의 문맥적 유사성을 기반으로 벡터를 생성합니다.\n",
      "예시: Word2Vec 모델에서 \"왕\"과 \"여왕\"은 서로 가까운 위치에 벡터로 표현됩니다.\n",
      "연관키워드: 자연어 처리, 임베딩, 의미론적 유사성\n",
      "LLM (Large Language Model)\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 5}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 2:\n",
      "\n",
      "Semantic Search\n",
      "\n",
      "정의: 의미론적 검색은 사용자의 질의를 단순한 키워드 매칭을 넘어서 그 의미를 파악하여 관련된 결과를 반환하는 검색 방식입니다.\n",
      "예시: 사용자가 \"태양계 행성\"이라고 검색하면, \"목성\", \"화성\" 등과 같이 관련된 행성에 대한 정보를 반환합니다.\n",
      "연관키워드: 자연어 처리, 검색 알고리즘, 데이터 마이닝\n",
      "\n",
      "Embedding\n",
      "\n",
      "정의: 임베딩은 단어나 문장 같은 텍스트 데이터를 저차원의 연속적인 벡터로 변환하는 과정입니다. 이를 통해 컴퓨터가 텍스트를 이해하고 처리할 수 있게 합니다.\n",
      "예시: \"사과\"라는 단어를 [0.65, -0.23, 0.17]과 같은 벡터로 표현합니다.\n",
      "연관키워드: 자연어 처리, 벡터화, 딥러닝\n",
      "\n",
      "Token\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 0}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 3:\n",
      "\n",
      "Token\n",
      "\n",
      "정의: 토큰은 텍스트를 더 작은 단위로 분할하는 것을 의미합니다. 이는 일반적으로 단어, 문장, 또는 구절일 수 있습니다.\n",
      "예시: 문장 \"나는 학교에 간다\"를 \"나는\", \"학교에\", \"간다\"로 분할합니다.\n",
      "연관키워드: 토큰화, 자연어 처리, 구문 분석\n",
      "\n",
      "Tokenizer\n",
      "\n",
      "정의: 토크나이저는 텍스트 데이터를 토큰으로 분할하는 도구입니다. 이는 자연어 처리에서 데이터를 전처리하는 데 사용됩니다.\n",
      "예시: \"I love programming.\"이라는 문장을 [\"I\", \"love\", \"programming\", \".\"]으로 분할합니다.\n",
      "연관키워드: 토큰화, 자연어 처리, 구문 분석\n",
      "\n",
      "VectorStore\n",
      "\n",
      "정의: 벡터스토어는 벡터 형식으로 변환된 데이터를 저장하는 시스템입니다. 이는 검색, 분류 및 기타 데이터 분석 작업에 사용됩니다.\n",
      "예시: 단어 임베딩 벡터들을 데이터베이스에 저장하여 빠르게 접근할 수 있습니다.\n",
      "연관키워드: 임베딩, 데이터베이스, 벡터화\n",
      "\n",
      "SQL\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 1}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 4:\n",
      "\n",
      "Parser\n",
      "\n",
      "정의: 파서는 주어진 데이터(문자열, 파일 등)를 분석하여 구조화된 형태로 변환하는 도구입니다. 이는 프로그래밍 언어의 구문 분석이나 파일 데이터 처리에 사용됩니다.\n",
      "예시: HTML 문서를 구문 분석하여 웹 페이지의 DOM 구조를 생성하는 것은 파싱의 한 예입니다.\n",
      "연관키워드: 구문 분석, 컴파일러, 데이터 처리\n",
      "\n",
      "TF-IDF (Term Frequency-Inverse Document Frequency)\n",
      "\n",
      "정의: TF-IDF는 문서 내에서 단어의 중요도를 평가하는 데 사용되는 통계적 척도입니다. 이는 문서 내 단어의 빈도와 전체 문서 집합에서 그 단어의 희소성을 고려합니다.\n",
      "예시: 많은 문서에서 자주 등장하지 않는 단어는 높은 TF-IDF 값을 가집니다.\n",
      "연관키워드: 자연어 처리, 정보 검색, 데이터 마이닝\n",
      "\n",
      "Deep Learning\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 8}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 5:\n",
      "\n",
      "정의: LLM은 대규모의 텍스트 데이터로 훈련된 큰 규모의 언어 모델을 의미합니다. 이러한 모델은 다양한 자연어 이해 및 생성 작업에 사용됩니다.\n",
      "예시: OpenAI의 GPT 시리즈는 대표적인 대규모 언어 모델입니다.\n",
      "연관키워드: 자연어 처리, 딥러닝, 텍스트 생성\n",
      "\n",
      "FAISS (Facebook AI Similarity Search)\n",
      "\n",
      "정의: FAISS는 페이스북에서 개발한 고속 유사성 검색 라이브러리로, 특히 대규모 벡터 집합에서 유사 벡터를 효과적으로 검색할 수 있도록 설계되었습니다.\n",
      "예시: 수백만 개의 이미지 벡터 중에서 비슷한 이미지를 빠르게 찾는 데 FAISS가 사용될 수 있습니다.\n",
      "연관키워드: 벡터 검색, 머신러닝, 데이터베이스 최적화\n",
      "\n",
      "Open Source\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 6}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 6:\n",
      "\n",
      "판다스 (Pandas)\n",
      "\n",
      "정의: 판다스는 파이썬 프로그래밍 언어를 위한 데이터 분석 및 조작 도구를 제공하는 라이브러리입니다. 이는 데이터 분석 작업을 효율적으로 수행할 수 있게 합니다.\n",
      "예시: 판다스를 사용하여 CSV 파일을 읽고, 데이터를 정제하며, 다양한 분석을 수행할 수 있습니다.\n",
      "연관키워드: 데이터 분석, 파이썬, 데이터 처리\n",
      "\n",
      "GPT (Generative Pretrained Transformer)\n",
      "\n",
      "정의: GPT는 대규모의 데이터셋으로 사전 훈련된 생성적 언어 모델로, 다양한 텍스트 기반 작업에 활용됩니다. 이는 입력된 텍스트에 기반하여 자연스러운 언어를 생성할 수 있습니다.\n",
      "예시: 사용자가 제공한 질문에 대해 자세한 답변을 생성하는 챗봇은 GPT 모델을 사용할 수 있습니다.\n",
      "연관키워드: 자연어 처리, 텍스트 생성, 딥러닝\n",
      "\n",
      "InstructGPT\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 11}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 7:\n",
      "\n",
      "HuggingFace\n",
      "\n",
      "정의: HuggingFace는 자연어 처리를 위한 다양한 사전 훈련된 모델과 도구를 제공하는 라이브러리입니다. 이는 연구자와 개발자들이 쉽게 NLP 작업을 수행할 수 있도록 돕습니다.\n",
      "예시: HuggingFace의 Transformers 라이브러리를 사용하여 감정 분석, 텍스트 생성 등의 작업을 수행할 수 있습니다.\n",
      "연관키워드: 자연어 처리, 딥러닝, 라이브러리\n",
      "\n",
      "Digital Transformation\n",
      "\n",
      "정의: 디지털 변환은 기술을 활용하여 기업의 서비스, 문화, 운영을 혁신하는 과정입니다. 이는 비즈니스 모델을 개선하고 디지털 기술을 통해 경쟁력을 높이는 데 중점을 둡니다.\n",
      "예시: 기업이 클라우드 컴퓨팅을 도입하여 데이터 저장과 처리를 혁신하는 것은 디지털 변환의 예입니다.\n",
      "연관키워드: 혁신, 기술, 비즈니스 모델\n",
      "\n",
      "Crawling\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 4}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 8:\n",
      "\n",
      "Deep Learning\n",
      "\n",
      "정의: 딥러닝은 인공신경망을 이용하여 복잡한 문제를 해결하는 머신러닝의 한 분야입니다. 이는 데이터에서 고수준의 표현을 학습하는 데 중점을 둡니다.\n",
      "예시: 이미지 인식, 음성 인식, 자연어 처리 등에서 딥러닝 모델이 활용됩니다.\n",
      "연관키워드: 인공신경망, 머신러닝, 데이터 분석\n",
      "\n",
      "Schema\n",
      "\n",
      "정의: 스키마는 데이터베이스나 파일의 구조를 정의하는 것으로, 데이터가 어떻게 저장되고 조직되는지에 대한 청사진을 제공합니다.\n",
      "예시: 관계형 데이터베이스의 테이블 스키마는 열 이름, 데이터 타입, 키 제약 조건 등을 정의합니다.\n",
      "연관키워드: 데이터베이스, 데이터 모델링, 데이터 관리\n",
      "\n",
      "DataFrame\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 9}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 9:\n",
      "\n",
      "DataFrame\n",
      "\n",
      "정의: DataFrame은 행과 열로 이루어진 테이블 형태의 데이터 구조로, 주로 데이터 분석 및 처리에 사용됩니다.\n",
      "예시: 판다스 라이브러리에서 DataFrame은 다양한 데이터 타입의 열을 가질 수 있으며, 데이터 조작과 분석을 용이하게 합니다.\n",
      "연관키워드: 데이터 분석, 판다스, 데이터 처리\n",
      "\n",
      "Attention 메커니즘\n",
      "\n",
      "정의: Attention 메커니즘은 딥러닝에서 중요한 정보에 더 많은 '주의'를 기울이도록 하는 기법입니다. 이는 주로 시퀀스 데이터(예: 텍스트, 시계열 데이터)에서 사용됩니다.\n",
      "예시: 번역 모델에서 Attention 메커니즘은 입력 문장의 중요한 부분에 더 집중하여 정확한 번역을 생성합니다.\n",
      "연관키워드: 딥러닝, 자연어 처리, 시퀀스 모델링\n",
      "\n",
      "판다스 (Pandas)\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 10}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 10:\n",
      "\n",
      "Page Rank\n",
      "\n",
      "정의: 페이지 랭크는 웹 페이지의 중요도를 평가하는 알고리즘으로, 주로 검색 엔진 결과의 순위를 결정하는 데 사용됩니다. 이는 웹 페이지 간의 링크 구조를 분석하여 평가합니다.\n",
      "예시: 구글 검색 엔진은 페이지 랭크 알고리즘을 사용하여 검색 결과의 순위를 정합니다.\n",
      "연관키워드: 검색 엔진 최적화, 웹 분석, 링크 분석\n",
      "\n",
      "데이터 마이닝\n",
      "\n",
      "정의: 데이터 마이닝은 대량의 데이터에서 유용한 정보를 발굴하는 과정입니다. 이는 통계, 머신러닝, 패턴 인식 등의 기술을 활용합니다.\n",
      "예시: 소매업체가 고객 구매 데이터를 분석하여 판매 전략을 수립하는 것은 데이터 마이닝의 예입니다.\n",
      "연관키워드: 빅데이터, 패턴 인식, 예측 분석\n",
      "\n",
      "멀티모달 (Multimodal)\n",
      "Metadata: {'source': './data/appendix-keywords.txt', 'id': 13}\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.document_loaders import TextLoader\n",
    "from langchain_community.vectorstores import FAISS\n",
    "from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
    "from langchain_openai import OpenAIEmbeddings\n",
    "\n",
    "# 문서 로드\n",
    "documents = TextLoader(\"./data/appendix-keywords.txt\").load()\n",
    "\n",
    "# 텍스트 분할기 초기화\n",
    "text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)\n",
    "\n",
    "# 문서 분할\n",
    "texts = text_splitter.split_documents(documents)\n",
    "\n",
    "# 각 텍스트에 고유 ID 추가\n",
    "for idx, text in enumerate(texts):\n",
    "    text.metadata[\"id\"] = idx\n",
    "    \n",
    "# 검색기 초기화\n",
    "retriever = FAISS.from_documents(\n",
    "    texts, OpenAIEmbeddings()\n",
    ").as_retriever(search_kwargs={\"k\": 10})\n",
    "\n",
    "# 질의문\n",
    "query = \"Word2Vec 에 대해서 설명해줘.\"\n",
    "\n",
    "# 문서 검색\n",
    "docs = retriever.invoke(query)\n",
    "\n",
    "# 문서 출력\n",
    "pretty_print_docs(docs)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b418f3c1",
   "metadata": {},
   "source": [
    "이제 기본 `retriever`를 `ContextualCompressionRetriever`로 감싸고, `FlashrankRerank`를 압축기로 사용해 봅시다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0c954ed6",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 4, 10]\n"
     ]
    }
   ],
   "source": [
    "from langchain.retrievers import ContextualCompressionRetriever\n",
    "from langchain.retrievers.document_compressors import FlashrankRerank\n",
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "# LLM 초기화\n",
    "llm = ChatOpenAI(temperature=0)\n",
    "\n",
    "# 문서 압축기 초기화\n",
    "compressor = FlashrankRerank(model=\"ms-marco-MultiBERT-L-12\")\n",
    "\n",
    "# 문맥 압축 검색기 초기화\n",
    "compression_retriever = ContextualCompressionRetriever(\n",
    "    base_compressor=compressor, base_retriever=retriever\n",
    ")\n",
    "\n",
    "# 압축된 문서 검색\n",
    "compressed_docs = compression_retriever.invoke(\n",
    "    \"Word2Vec 에 대해서 설명해줘.\"\n",
    ")\n",
    "\n",
    "# 문서 ID 출력\n",
    "print([doc.metadata[\"id\"] for doc in compressed_docs])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ffa1cd05",
   "metadata": {},
   "source": [
    "reranker 가 적용된 후 결과를 비교합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "435e3de3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Document 1:\n",
      "\n",
      "Semantic Search\n",
      "\n",
      "정의: 의미론적 검색은 사용자의 질의를 단순한 키워드 매칭을 넘어서 그 의미를 파악하여 관련된 결과를 반환하는 검색 방식입니다.\n",
      "예시: 사용자가 \"태양계 행성\"이라고 검색하면, \"목성\", \"화성\" 등과 같이 관련된 행성에 대한 정보를 반환합니다.\n",
      "연관키워드: 자연어 처리, 검색 알고리즘, 데이터 마이닝\n",
      "\n",
      "Embedding\n",
      "\n",
      "정의: 임베딩은 단어나 문장 같은 텍스트 데이터를 저차원의 연속적인 벡터로 변환하는 과정입니다. 이를 통해 컴퓨터가 텍스트를 이해하고 처리할 수 있게 합니다.\n",
      "예시: \"사과\"라는 단어를 [0.65, -0.23, 0.17]과 같은 벡터로 표현합니다.\n",
      "연관키워드: 자연어 처리, 벡터화, 딥러닝\n",
      "\n",
      "Token\n",
      "Metadata: {'id': 0, 'relevance_score': 0.9997491, 'source': './data/appendix-keywords.txt'}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 2:\n",
      "\n",
      "HuggingFace\n",
      "\n",
      "정의: HuggingFace는 자연어 처리를 위한 다양한 사전 훈련된 모델과 도구를 제공하는 라이브러리입니다. 이는 연구자와 개발자들이 쉽게 NLP 작업을 수행할 수 있도록 돕습니다.\n",
      "예시: HuggingFace의 Transformers 라이브러리를 사용하여 감정 분석, 텍스트 생성 등의 작업을 수행할 수 있습니다.\n",
      "연관키워드: 자연어 처리, 딥러닝, 라이브러리\n",
      "\n",
      "Digital Transformation\n",
      "\n",
      "정의: 디지털 변환은 기술을 활용하여 기업의 서비스, 문화, 운영을 혁신하는 과정입니다. 이는 비즈니스 모델을 개선하고 디지털 기술을 통해 경쟁력을 높이는 데 중점을 둡니다.\n",
      "예시: 기업이 클라우드 컴퓨팅을 도입하여 데이터 저장과 처리를 혁신하는 것은 디지털 변환의 예입니다.\n",
      "연관키워드: 혁신, 기술, 비즈니스 모델\n",
      "\n",
      "Crawling\n",
      "Metadata: {'id': 4, 'relevance_score': 0.9997148, 'source': './data/appendix-keywords.txt'}\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 3:\n",
      "\n",
      "DataFrame\n",
      "\n",
      "정의: DataFrame은 행과 열로 이루어진 테이블 형태의 데이터 구조로, 주로 데이터 분석 및 처리에 사용됩니다.\n",
      "예시: 판다스 라이브러리에서 DataFrame은 다양한 데이터 타입의 열을 가질 수 있으며, 데이터 조작과 분석을 용이하게 합니다.\n",
      "연관키워드: 데이터 분석, 판다스, 데이터 처리\n",
      "\n",
      "Attention 메커니즘\n",
      "\n",
      "정의: Attention 메커니즘은 딥러닝에서 중요한 정보에 더 많은 '주의'를 기울이도록 하는 기법입니다. 이는 주로 시퀀스 데이터(예: 텍스트, 시계열 데이터)에서 사용됩니다.\n",
      "예시: 번역 모델에서 Attention 메커니즘은 입력 문장의 중요한 부분에 더 집중하여 정확한 번역을 생성합니다.\n",
      "연관키워드: 딥러닝, 자연어 처리, 시퀀스 모델링\n",
      "\n",
      "판다스 (Pandas)\n",
      "Metadata: {'id': 10, 'relevance_score': 0.9997084, 'source': './data/appendix-keywords.txt'}\n"
     ]
    }
   ],
   "source": [
    "# 문서 압축 결과 출력\n",
    "pretty_print_docs(compressed_docs)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain-kr-lwwSZlnu-py3.11",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
